package com.ruoyi.framework.front.service;

import com.ruoyi.api.domain.UserEntity;
import com.ruoyi.api.repository.UserRepository;
import com.ruoyi.api.service.UserService;
import com.ruoyi.common.core.domain.model.RegistParam;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;

import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.front.domain.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;


@Component
public class UserLoiginService {

    @Autowired
    private UserTokenService tokenService;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private UserService userService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private UserRepository userRepository;
//    @Autowired
//    private JavaMailSenderImpl mailSender;
    @Autowired
    private JavaMailSender javaMailSender;
    @Value("${spring.mail.username}")
    private String username;
    private static final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    public Map<String,Object> login(String email, String passWord) {
        Map<String,Object> resmap = new HashMap<>();
        UserEntity entity = userService.selectUserByEmail(email);
        if (null == entity ){
            throw new ServiceException("Email fail");
        }

        userService.validatePassword(passWord,entity.getPassWord());
        // 用户验证
        String token =  tokenService.createToken(new LoginUser(entity));
        //存redis
        Map<String,UserEntity> map = redisCache.getCacheMap("token");
        map.put(token,entity);
        redisCache.setCacheMap("token",map);
        // 生成token
        resmap.put("token",token);
        resmap.put("user",entity);
        return resmap;
    }

    public Map<String,Object> regist(RegistParam registParam) {

        if(null==registParam.getCode()){
            throw new ServiceException("code fail");
        }
        if(null!=registParam.getCode()){
           if(!redisCache.hasKey("registCode-"+registParam.getEmail())){
               throw new ServiceException("code fail");
           }
           String redisCode = redisCache.getCacheObject("registCode-"+registParam.getEmail())+"";
            if(!redisCode.equals(registParam.getCode())){
                throw new ServiceException("code fail");
            }
            redisCache.deleteObject("registCode-"+registParam.getEmail());
            userService.regist(registParam);
        }

        return login(registParam.getEmail(),registParam.getPassword());
    }

    public Map<String, Object> loginByGoogle(UserEntity entity) {
        Map<String,Object> resmap = new HashMap<>();
        UserEntity userEntity = userService.selectUserByEmail(entity.getEmail());
        if (null == userEntity ){
            userRepository.save(entity);
            // 用户验证
            String token =  tokenService.createToken(new LoginUser(entity));
            //存redis
            Map<String,UserEntity> map = redisCache.getCacheMap("token");
            map.put(token,entity);
            redisCache.setCacheMap("token",map);
            // 生成token
            resmap.put("token",token);
            resmap.put("user",entity);
        }else{
            // 用户验证
            String token =  tokenService.createToken(new LoginUser(userEntity));
            //存redis
            Map<String,UserEntity> map = redisCache.getCacheMap("token");
            map.put(token,userEntity);
            redisCache.setCacheMap("token",map);
            // 生成token
            resmap.put("token",token);
            resmap.put("user",userEntity);
        }

        return resmap;
    }




    public Boolean getCode(RegistParam registParam) {

        if(redisCache.hasKey(registParam.getType()+"-"+registParam.getEmail())){
            return true;
        }
        Random random = new Random();
        String code = 100000 + random.nextInt(900000)+"";

        redisCache.setCacheObject(registParam.getType() + "-"+registParam.getEmail(),code,10, TimeUnit.MINUTES);

        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

            helper.setTo(registParam.getEmail());
            helper.setSubject("Complete Your Swiftour Registration");
            helper.setFrom(username);

            String htmlContent = "<p>Hello,</p>" +
                    "<p>Thank you for registering with Swiftour. To complete your registration, please use the following verification code:</p>" +
                    "<table width='100%' style='background-color: #f0f0f0;'><tr><td style='text-align: center; font-weight: bold; color: black; padding: 10px;'>" + code + "</td></tr></table>" +
                    "<p>Enter this code on the verification page to activate your account. This code will expire in 10 minutes.</p>" +
                    "<p>If you didn't request this code, please ignore this email.</p>" +
                    "<p>If you have any questions or need assistance, please contact our support team at <a href='mailto:swiftour@outlook.com'>swiftour@outlook.com</a>.</p>" +
                    "<p>Best regards,<br>The Swiftour Team</p>";

            if(registParam.getType().equals("resetCode")){
                helper.setSubject("Password Reset Request");
                htmlContent   = "<p>Hello,</p>" +
                        "<p>We received a request to reset your password for your Swiftour account. If you didn't make this request, please ignore this email.\n" +
                        "To reset your password, use the following code:</p>" +
                        "<table width='100%' style='background-color: #f0f0f0;'><tr><td style='text-align: center; font-weight: bold; color: black; padding: 10px;'>" + code + "</td></tr></table>" +
                        "<p>Enter this code on the password reset page to create a new password. This code will expire in 15 minutes for security reasons.</p>" +
                        "<p>If you're having trouble, please contact our support team at <a href='mailto:swiftour@outlook.com'>swiftour@outlook.com</a>.</p>" +
                        "<p>Best regards,<br>The Swiftour Team</p>";
            }
            helper.setText(htmlContent, true);

            javaMailSender.send(mimeMessage);

        } catch (MessagingException e) {
            e.printStackTrace();
        }


        return true;
    }

    public Boolean resetCodeConfirm(RegistParam registParam) {
        if(null==registParam.getCode()){
            throw new ServiceException("code fail");
        }
        if(null!=registParam.getCode()){
            if(!redisCache.hasKey("resetCode-"+registParam.getEmail())){
                throw new ServiceException("code fail");
            }
            String redisCode = redisCache.getCacheObject("resetCode-"+registParam.getEmail())+"";
            if(!redisCode.equals(registParam.getCode())){
                throw new ServiceException("code fail");
            }

        }
        return true;
    }

    public Boolean resetPassword(RegistParam registParam) {
        redisCache.deleteObject("resetCode-"+registParam.getEmail());
        UserEntity userEntity = userRepository.findByEmail(registParam.getEmail());
//        userEntity.setPassWord(Argon2Utils.hashPassword(registParam.getPassword()));
        userEntity.setPassWord(SecurityUtils.encryptPassword(registParam.getPassword()));
        return userService.update(UserEntity.class,userEntity,mongoTemplate);
    }
}
